import type { Router } from 'vue-router';

import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
import { preferences } from '@vben/preferences';
import { useAccessStore, useUserStore } from '@vben/stores';
import { cloneDeep, startProgress, stopProgress } from '@vben/utils';

import { accessRoutes, coreRouteNames } from '#/router/routes';
// import { useAuthStore } from '#/store';

import { BasicLayout } from '#/layouts';

import { generateAccess } from './access';

const pageMap: any = import.meta.glob('../views/**/*.vue');
/**
 * 通用守卫配置
 * @param router
 */
function setupCommonGuard(router: Router) {
  // 记录已经加载的页面
  const loadedPaths = new Set<string>();

  router.beforeEach(async (to) => {
    to.meta.loaded = loadedPaths.has(to.path);

    // 页面加载进度条
    if (!to.meta.loaded && preferences.transition.progress) {
      startProgress();
    }
    return true;
  });

  router.afterEach((to) => {
    // 记录页面是否加载,如果已经加载，后续的页面切换动画等效果不在重复执行

    loadedPaths.add(to.path);

    // 关闭页面加载进度条
    if (preferences.transition.progress) {
      stopProgress();
    }
  });
}

/**
 * 权限访问守卫配置
 * @param router
 */
function setupAccessGuard(router: Router) {
  router.beforeEach(async (to, from) => {
    const accessStore = useAccessStore();
    const userStore = useUserStore();
    // const authStore = useAuthStore();

    // 基本路由，这些路由不需要进入权限拦截
    if (coreRouteNames.includes(to.name as string)) {
      if (to.path === LOGIN_PATH && accessStore.accessToken) {
        return decodeURIComponent(
          (to.query?.redirect as string) || DEFAULT_HOME_PATH,
        );
      }
      return true;
    }

    // accessToken 检查
    if (!accessStore.accessToken) {
      // 明确声明忽略权限访问权限，则可以访问
      if (to.meta.ignoreAccess) {
        return true;
      }

      // 没有访问权限，跳转登录页面
      if (to.fullPath !== LOGIN_PATH) {
        return {
          path: LOGIN_PATH,
          // 如不需要，直接删除 query
          query: { redirect: encodeURIComponent(to.fullPath) },
          // 携带当前跳转的页面，登录后重新跳转该页面
          replace: true,
        };
      }
      return to;
    }

    // 是否已经生成过动态路由
    if (accessStore.isAccessChecked) {
      return true;
    }

    // const data = await requestApi(
    //   '/api/role/GetRoutersForAccessToken',
    //   {},
    //   'get',
    // );
    const data = [
      {
        id: 9,
        parent_right_id: -1,
        right_name: '安全承诺公告',
        right_no: 'N001',
        menu_type: 'C',
        right_desc: '',
        del_flag: 0,
        create_date: '2024-06-30 22:19:55',
        created_by: '超级管理员',
        modify_date: '2024-11-18 15:47:10',
        modified_by: '超级管理员',
        path: '/entpromise',
        alwaysShow: '',
        redirect: '',
        icon: 'lucide:bandage',
        component: '',
        sort_num: 1000,
        target: '_self',
        isShow: 0,
        activeMenu: '',
        role_id: 2,
        checked: 1,
        disabled: 0,
        children: [
          {
            id: 11,
            parent_right_id: 9,
            right_name: '车间研判',
            right_no: 'N00102',
            menu_type: 'C',
            right_desc: '',
            del_flag: 0,
            create_date: '2024-06-30 22:23:59',
            created_by: '超级管理员',
            modify_date: '2024-09-14 14:47:53',
            modified_by: '超级管理员',
            path: '/entpromiseWorkshop',
            alwaysShow: '',
            redirect: '',
            icon: 'lucide:area-chart',
            component: 'entpromise/entpromiseWorkshop',
            sort_num: 10_000,
            target: '_self',
            isShow: 0,
            activeMenu: '',
            checked: 1,
            disabled: 0,
          },
          {
            id: 12,
            parent_right_id: 9,
            right_name: '公司研判',
            right_no: 'N00103',
            menu_type: 'C',
            right_desc: '',
            del_flag: 0,
            create_date: '2024-06-30 22:24:52',
            created_by: '超级管理员',
            modify_date: '2024-09-14 14:48:21',
            modified_by: '超级管理员',
            path: '/entpromiseCompany',
            alwaysShow: '',
            redirect: '',
            icon: 'lucide:area-chart',
            component: 'entpromise/entpromiseCompany',
            sort_num: 10_000,
            target: '_self',
            isShow: 0,
            activeMenu: '',
            role_id: 2,
            checked: 1,
            disabled: 0,
          },
        ],
      },
      {
        id: 1002,
        parent_right_id: -1,
        right_name: '系统管理',
        right_no: 'submenu',
        menu_type: 'M',
        right_desc: '',
        del_flag: 0,
        create_date: '2022-09-12 00:46:39',
        created_by: '管理员',
        modify_date: '2024-05-22 07:39:21',
        modified_by: '管理员',
        path: '/submenu',
        icon: 'lucide:bandage',
        alwaysShow: '',
        redirect: '',
        component: '',
        sort_num: 100_000,
        target: '_self',
        isShow: 0,
        activeMenu: '',
        role_id: 2,
        checked: 1,
        disabled: 0,
        children: [
          {
            id: 7,
            parent_right_id: 1002,
            right_name: '通用Api接口配置',
            right_no: 'N001034',
            menu_type: 'C',
            right_desc: '',
            del_flag: 0,
            create_date: '2022-09-23 17:49:41',
            created_by: '管理员',
            modify_date: '2024-11-10 00:09:45',
            modified_by: '超级管理员',
            path: '/apiConfig',
            alwaysShow: '',
            redirect: '',
            icon: 'lucide:area-chart',
            component: 'submenu/apiConfig',
            sort_num: 1,
            target: '_self',
            isShow: 0,
            activeMenu: '',
            role_id: 2,
            checked: 1,
            disabled: 0,
          },
        ],
      },
    ];
    formatMenu(data);
    const arr = convertRouter(cloneDeep(data));
    arr.push({
      name: 'Analytics2',
      path: '/analytics2',
      component: () => import('#/views/dashboard/analytics/index.vue'),
      meta: {
        affixTab: true,
        icon: 'lucide:area-chart',
        title: '模仿看板',
        openInNewWindow: true,
      },
    });
    // 生成路由表
    // 当前登录用户拥有的角色标识列表
    const userInfo: any = userStore.userInfo || {};
    const userRoles = userInfo.roles ?? [];
    // console.log(accessRoutes, 'accessRoutes');
    // 生成菜单和路由
    const { accessibleMenus, accessibleRoutes } = await generateAccess({
      roles: userRoles,
      router,
      // 则会在菜单中显示，但是访问会被重定向到403
      routes: [...arr, ...accessRoutes],
    });
    // 保存菜单信息和路由信息
    accessStore.setAccessMenus(accessibleMenus);
    accessStore.setAccessRoutes(accessibleRoutes);
    accessStore.setIsAccessChecked(true);
    const redirectPath = (from.query.redirect ?? to.fullPath) as string;

    return {
      ...router.resolve(decodeURIComponent(redirectPath)),
      replace: true,
    };
  });
}

/**
 * 项目守卫配置
 * @param router
 */
function createRouterGuard(router: Router) {
  /** 通用 */
  setupCommonGuard(router);
  /** 权限访问 */
  setupAccessGuard(router);
}
// 格式化菜单
function formatMenu(data: Array<any> = [], path: string = ''): void {
  data.map((item: any) => {
    if (item.component) {
      item.component = `../views/${item.component}.vue`;
    } else {
      item.component =
        item.children && item.children.length > 0
          ? 'Layout'
          : `../views${path}/${item.path}/index.vue`;
    }
    item.name = item.right_name;
    item.meta = {
      title: item.right_name,
      icon: item.icon,
      // short_title: item.shortName,
      order: item.parent_right_id,
      target: item.target,
      openInNewWindow: item.target === '_blank',
      hideInMenu: item.isShow === 1,
      activePath: item.activeMenu || item.path, // 激活的菜单路径
    };
    if (item.children) formatMenu(item.children, `${path}/${item.path}`);
  });
}
function convertRouter(asyncRoutes: any[]) {
  return asyncRoutes.map((route: any) => {
    if (route.component) {
      const component = route.component;
      // console.log(pageMap[], 'pageMap');
      if (component) {
        component === 'Layout'
          ? (route.component = BasicLayout)
          : (route.component = pageMap[component]);
      } else {
        // eslint-disable-next-line no-throw-literal
        throw `后端路由加载失败，请输入'Layout'或以'#/'开头的本地组件地址: ${route.component}`;
      }
    }
    route = {
      name: route.right_name,
      path: route.path,
      meta: {
        ...route.meta,
      },
      redirect: route.redirect,
      component: route.component,
      children: route.children,
    };
    if (route.children)
      route.children.length > 0
        ? (route.children = convertRouter(route.children))
        : delete route.children;

    return route;
  });
}
export { createRouterGuard };
